package com.sky.handler;

import com.sky.constant.MessageConstant;
import com.sky.exception.BaseException;
import com.sky.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理器，处理项目中抛出的业务异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 捕获业务异常
     * @param ex
     * @return
     */
    //这里是全局异常处理器，统一处理所有异常
    //刚刚从EmployeeServiceImpl中的if的自定义异常过来，这里也不是捕获AccountNotFoundException，而是BaseException，为啥？
    //解答：这里BaseException，我们捕获的是一个大的父类异常，刚刚看到的AccountNotFoundException是BaseException的子类，在sky-common下的exception包中，AccountNotFoundException继承BaseException
    @ExceptionHandler
    public Result exceptionHandler(BaseException ex){
        log.error("异常信息：{}", ex.getMessage());
        return Result.error(ex.getMessage());   //捕获到后，给我们前端返回一个结果
    }

    /**
     * 处理SQl异常  刚开始还没有写唯一代码程序报的异常
     * @param ex
     * @return
     */
    //追加一个方法，用来处理刚才新增重复id员工报的SQLIntegrityConstraintViolationException异常，也就是数据库唯一性异常
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        //Duplicate entry 'zhangsan' for key 'idx_username'
        String message = ex.getMessage();   //通过ex.getMessage获得异常信息
        //判断一下异常信息有没有包含Duplicate entry 'zhangsan' for key 'idx_username'的Duplicate entry，这两个单词叫重复的键值对，如果包含就可以确认是这个异常
        //我们希望给前端’zhangsan‘这个用户名已存在这个提示信息，也就是需要动态的把’zhangsan‘这个字符串给提取出来，怎么提取？看这个错误信息，可以考虑用空格进行分隔提取出来，从而得到一个数组对象，数组第三个就是’zhangsan‘
        if (message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            //取到后，就可以拼这么一个字符串，说我们用户名已存在
            String msg = username + MessageConstant.ALREAEDY_EXISTS;      //String msg = username + "已存在"; 为了规范使用，“已存在”使用常量类
            //返回的是Result对象。最后在封装一下,这样前端就可以正常去提示这个信息
            return Result.error(msg);
        }
        else {  //如果是else，这时候我们不知道发生什么情况，这时候直接返回"未知错误"，使用常量类
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }
}
